'''
$Log
'''
import unittest
from VendingMachine import *

class VendingMachineTest(unittest.TestCase):


    def setUp(self):
        self.vm = VendingMachine()
        self.vm.setNumberOfButtons(5)
        self.vm.inputMoney(1000)
        self.vm.inputMoney(1000)
        self.vm.addMenu('coffee', 200, 5)
        self.vm.addMenu('greentea', 300, 2)
        self.vm.addMenu('milk', 150)
        self.vm.addMenu('coffee', 200, 3)      
        self.vm.setMaxStackSize(20)
        self.vm.pushCans(3, 10)
        self.vm.pushCans(2, 5)
        self.vm.pushCans(1, 5)
        self.vm.pushCans(5, 5)
        self.vm.pushCans(3, 15)
        

    def testSingleton(self):
        vm1 = VendingMachine()
        vm2 = VendingMachine()
        self.assertEquals(vm1, vm2)


    def testaddMenu(self):
        self.assertEquals(self.vm.menu[5][0], 'coffee')
        self.assertEquals(self.vm.menu[1][0], 'milk')
        self.assertEquals(self.vm.menu[3][0], 'coffee')
        self.assertEquals(self.vm.menu[5][1], 200)
        self.assertEquals(self.vm.menu[1][1], 150)

    def testpushCoins(self):
        self.assertEquals(self.vm.pushCoins(500,10), 10)
        self.assertEquals(self.vm.pushCoins(500,5), 15)

    def testgetCoin(self):
        self.vm.pushCoins(500,10)                       
        self.vm.pushCoins(100, 3)
        self.assertEquals(self.vm.getCoinStack(100), 3)
        self.assertEquals(self.vm.getCoinStackInfo(), {10000:0, 5000:0, 1000:0, 500:10, 100:3, 50:0, 10:0})

    def testgetNumberOfButtom(self):
        self.assertEquals(self.vm.getNumberOfButtons(), 5)

    def testStack(self):
        self.assertEquals(self.vm.getMaxStackSize(), 20)
        self.assertEquals(self.vm.getStackSize(3), 20)
        self.assertEquals(self.vm.getStackSize(2), 5)
        self.assertEquals(self.vm.getStackSize(5), 5)
        self.assertEquals(self.vm.getStackSize('greentea'), 5)
        self.assertEquals(self.vm.getStackSize('coffee'), 25)
        self.assertEquals([self.vm.getStackSize(Number) for Number in self.vm.menu.keys()], [5, 5, 20, 5])
        self.assertEquals([self.vm.getStackSize(self.vm.menu[Number][0]) for Number in self.vm.menu.keys()], [5, 5, 25, 25]) 


    def testgetMenu(self):
        self.assertEquals(str(self.vm), '1 : milk\n2 : greentea\n3 : coffee\n5 : coffee\n')

    def testavailable(self):
        self.assertEquals(self.vm.availableMenuList(), ['coffee', 'coffee', 'greentea', 'milk'])
        self.assertEquals(self.vm.availableButtons(), [1, 2, 3, 5])

    def testgetBy(self):
        self.assertEquals(self.vm.getNameByButtonId(3), 'coffee')
        self.assertEquals(self.vm.getNameByButtonId(1), 'milk')
        self.assertEquals(self.vm.getButtonIdByName('coffee'), 3)
        self.assertEquals(self.vm.getButtonIdByName('milk'), 1)


    def testbuyByMenu(self):
        self.assertEquals(self.vm.buyByMenu('coffee'), 1800)
        self.assertEquals(self.vm.buyByMenu('greentea'), 1500)

    def testbuyByButton(self):
        self.assertEquals(self.vm.buyByButton(1), 1850)
        self.assertEquals(self.vm.buyByButton(2), 1550)

    def testselectMenu(self):
        self.vm.selectMenu(3)
        self.assertEquals(self.vm.getStackSize(3), 19)
        self.assertEquals(self.vm.getChange(), 1800)
        self.vm.selectMenu(3)
        self.assertEquals(self.vm.getStackSize(3), 18)
        self.assertEquals(self.vm.getChange(), 1600)
        self.vm.selectMenu(2)
        self.assertEquals(self.vm.getStackSize(2), 4)
        self.assertEquals(self.vm.getChange(), 1300)
        self.vm.inputMoney(500)
        self.assertEquals(self.vm.getChange(), 1800)
        for k in range(5):
            self.vm.selectMenu(5)
        self.assertEquals(self.vm.getStackSize(5), 0)
        self.assertEquals(self.vm.getChange(), 800)
        self.assertRaises(EmptyStack, self.vm.selectMenu, 5)
        
    def testchangeToCoins(self):
        self.vm.pushCoins(500,10)                       
        self.vm.pushCoins(100,10)
        self.vm.buyByMenu('coffee')
        self.assertEquals(self.vm.changeToCoins(),{10000:0, 5000:0, 1000:0, 500:3, 100:3, 50:0, 10:0})

    def testNotEnoughSpairCoins(self):
        self.vm.pushCoins(500,1) 
        self.vm.pushCoins(100,1) 
        self.assertRaises(NotEnoughSpairCoins, self.vm.changeToCoins)
        

    def testgetNumberOfItemsSold(self):
        self.vm.selectMenu(3)
        self.vm.selectMenu(3)
        self.assertEquals(self.vm.getNumberOfItemsSold('coffee'), 2)

    def testgetIncome(self):
        self.vm.selectMenu(3)
        self.vm.selectMenu(2)
        self.vm.inputMoney(5000)
        self.vm.inputMoney(500)
        self.vm.selectMenu(2)
        self.assertEquals(self.vm.getIncomeInfo(), {10:0, 50:0, 100:0, 500:1, 1000:2, 5000:1, 10000:0}) 
        self.assertEquals(self.vm.getTotalIncome(), 7500)

    def testgetTotalSale(self):
        self.vm.pushCoins(1000,10)
        self.vm.pushCoins(500,10)
        self.vm.pushCoins(100,10) 
        self.vm.selectMenu(3)
        self.vm.selectMenu(2)
        self.vm.changeToCoins()
        self.vm.inputMoney(5000)
        self.vm.selectMenu(2)
        self.vm.changeToCoins()
        self.assertEquals(self.vm.getTotalSale(), 800)

    def testSendEventMessage(self):
        self.vm.pushCoins(1000,10)
        self.vm.pushCoins(100,10)
        self.vm.inputMoney(500)
        self.assertEquals(self.vm.getSocketLog(), '''>>> ID : 1\n>>> EVENT : MONEY_INPUT 500\n<<< QUIT\n''')
        self.vm.selectMenu(2)
        self.assertEquals(self.vm.getSocketLog(), '''>>> ID : 1\n>>> EVENT : SELL greentea\t300\n<<< QUIT\n''')
        self.vm.changeToCoins()
        self.assertEquals(self.vm.getSocketLog(), '>>> ID : 1\n>>> EVENT : GIVE_CHANGE {100: 2, 5000: 0, 10: 0, 10000: 0, 1000: 2, 50: 0, 500: 0}\n<<< QUIT\n')
                
if __name__== '__main__':
    unittest.main(argv=('', '-v'))

